#  StormMUD - A multiplayer combat game - http://stormmud.david-c-brown.com
#  Copyright (C) 2009, 2010 - David C Brown & Mark Richardson
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Twisted imports
from twisted.internet import reactor

# StormMUD imports
from smDefines import WHITE, GREEN, YELLOW, BLUE
from smDefines import NORTH, NE, EAST, SE, SOUTH, SW, WEST, NW, UP, DOWN
from smDefines import DIRS
from smMaps import WORLD, Rooms, Doors, GetRoomByID
#from smPlayer import Player, PlayersInGame

MOVINGTEXT = {  1: " leaves to the north.| arrives from the south.",
                2: " leaves to the northeast.| arrives from the southwest.",
                3: " leaves to the east.| arrives from the west.",
                4: " leaves to the southeast.| arrives from the northwest.",
                5: " leaves to the south.| arrives from the north.",
                6: " leaves to the southwest.| arrives from the northeast.",
                7: " leaves to the west.| arrives from the east.",
                8: " leaves to the northwest.| arrives from the southeast.",
                9: " leaves up .| arrives from below.",
               10: " leaves down.| arrives from above.",
             }

SNEAKINGTEXT = {  1: " sneaking out to the north.| sneaking in from the south.",
                  2: " sneaking out to the northeast.| sneaking in from the southwest.",
                  3: " sneaking out to the east.| sneaking in from the west.",
                  4: " sneaking out to the southeast.| sneaking in from the northwest.",
                  5: " sneaking out to the south.| sneaking in from the north.",
                  6: " sneaking out to the southwest.| sneaking in from the northeast.",
                  7: " sneaking out to the west.| sneaking in from the east.",
                  8: " sneaking out to the northwest.| sneaking in from the southeast.",
                  9: " sneaking out up .| sneaking in from below.",
                 10: " sneaking out down.| sneaking in from above.",
             }

# Base movement delay
MOVEMENT_DELAY = .5

#===============================================
# Command -> QUIT
#===============================================
def Quit(player):
   """Quit():  User command to disconnect"""
   
   player.disconnectClient()

#===============================================
# Command -> Say
#===============================================
def Say(player, line):
   """Say(): Says a players text to the room"""
   
   player.sendToRoom(GREEN + player.name + " says: " + WHITE + line)
   player.sendToPlayer(GREEN + "You say: " + WHITE + line + WHITE)
   
#===============================================
# Rest()
#===============================================
def Rest(player):
   player.resting = True
   # TODO: Later add break combat, etc
   
   player.sendToPlayer("%sYou stop to rest." % (WHITE))
   player.sendToRoom("%s%s stops to rest." % (WHITE, player.name))
   return

#===============================================
# Command -> LookRoom()
#===============================================
def LookRoom(player, roomid):
   """
   LookRoom()
   Displays the room defined by roomid
   """
   CurRoom = WORLD['MAIN'].rooms[roomid]
   PLAYERCOUNT = 0
   # If players room, set 1 one, otherwise set to zero
   if roomid == player.room:
      PLAYERCOUNT = 1
   
   player.sendToPlayer("%s" % (CurRoom.name) )
   if len(CurRoom.PlayersInRoom) > PLAYERCOUNT:
      player.sendToPlayer("%s%s" % (CurRoom.GetAlsoHere(player.name), WHITE) )
   player.sendToPlayer("%s" % (CurRoom.GetObviousExits()) )
   
   
#===============================================
# CallMovePlayer()
#===============================================
def CallMovePlayer(player, direction):
   """
   CallMovePlayer()
   This function processes everything that needs
   to be done before physically calling MovePlayer()
   with the required delay.
   """
   player.moving = True
   reactor.callLater(MOVEMENT_DELAY, MovePlayer, player, direction)
    
#===============================================
# MovePlayer()
#===============================================
def MovePlayer(player, direction):
   """
   MovePlayer()
   Moves the player from one room to another
   """

    # Sub function that can be called when a player's path is blocked.
   def RunIntoWall(PassageType, playerName):
      theDir = DIRS[direction]

      ToPlayer = "You run into the %s %s!" % (PassageType, theDir)
      ToRoom = "%s runs into the %s %s!" % (player.name, PassageType, theDir)
      player.sendToPlayer("%s%s%s" % (BLUE, ToPlayer, WHITE) )
      player.sendToRoom("%s%s%s" % (WHITE, ToRoom, WHITE) )
      
      
   player.resting    = False
   player.sneaking   = False
   MAP = player.room.split("|")[0]

   # If the player is held or stun, he can't move!
   if player.held:
      player.moving = 0
      player.sendToPlayer("You cannot move!")
      player.sendToRoomNotVictim( player.playerid, "%s%s struggles to move!" % (YELLOW, player.name) )
      player.moving = False
      return None
   elif player.stun:
      player.moving = 0
      player.sendToPlayer("You stumble about dazedly and cannot move!")
      player.sendToRoomNotVictim( player.playerid, "%s%s stumbles about dazedly!" % (WHITE, player.name) )
      player.moving = False
      return None

      
   # Does the room have a door in that direction?
   if direction in WORLD[MAP].rooms[player.room].doors:
      CurDoor = WORLD[MAP].rooms[player.room].doors[direction]
      CurRoom = GetRoomByID(player.room)
      NewRoom = GetRoomByID(CurDoor.ExitRoom[player.room])
   else:
      RunIntoWall("wall", player.name)
      player.moving = False
      return
      
   if CurDoor.passable:
      MOVING = MOVINGTEXT[direction].split('|')
      player.sendToRoom(WHITE + player.name + MOVING[0])
      CurRoom.RemovePlayerFromRoom(player)
      player.room = NewRoom.RoomID
      NewRoom.AddPlayerToRoom(player)
      player.sendToRoom(WHITE + player.name + MOVING[1])
      LookRoom(player, player.room)
   else:
      RunIntoWall(CurDoor.DoorText, player.name)
      player.moving = False
      return
   
   player.moving = False
   if len(player.CmdStack) > 0: 
      player.PopCmdStack()
      
